package com.aljfce.business.profile.boundary;

import com.aljfce.business.entity.Calendar;
import com.aljfce.business.entity.Event;
import com.aljfce.business.entity.Notification;
import com.aljfce.business.entity.User;
import com.aljfce.business.event.boundary.CreateEvent;
import com.aljfce.business.event.control.EventWrapper;
import com.aljfce.business.notification.boundary.NotificationBean;
import com.aljfce.business.notification.control.NotificationManager;
import com.aljfce.business.notification.exception.NotificationNotFoundException;
import com.aljfce.business.profile.control.LoginManager;
import com.aljfce.business.profile.control.ProfileManager;
import com.aljfce.business.profile.control.UserDataLoader;
import com.aljfce.business.profile.exception.CalendarNotFoundEception;
import com.aljfce.business.profile.exception.UserNotFoundException;
import com.aljfce.business.search.control.SearchManager;
import java.io.Serializable;
import java.security.Principal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;

import javax.faces.context.FacesContext;

import javax.inject.Inject;

import javax.servlet.http.HttpServletRequest;
import org.joda.time.DateTime;
import org.joda.time.DateTimeComparator;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;

/**
 *
 * @author EOroan, Antonio, Jacopo
 */
@ManagedBean(eager = true)
@ViewScoped

public class UserHome implements Serializable {

    @Inject
    NotificationManager notificationManager;

    @Inject
    LoginManager lm;

    @Inject
    UserDataLoader userDataLoader;

    @Inject
    ProfileManager pm;

    @Inject
    SearchManager sm;

    @ManagedProperty(value = "#{notificationBean}")
    NotificationBean notificationBean;

    private Event selectedEvent;

    private ArrayList<Event> eventsList;

    public Event getSelectedEvent() {
        return selectedEvent;
    }

    public void setSelectedEvent(Event selectedEvent) {
        this.selectedEvent = selectedEvent;
    }

    public void onEventSelect(SelectEvent selectEvent) {
        EventWrapper ew = (EventWrapper) selectEvent.getObject();
        this.selectedEvent = ew.getEvent();

    }

    public ArrayList<Event> getEventsList() {
        return eventsList;
    }

    public void setEventsList(ArrayList<Event> eventsList) {
        this.eventsList = eventsList;
    }

    private User currentUser;

    /**
     * Get the value of currentUser
     *
     * @return the value of currentUser
     */
    public User getCurrentUser() {
        return currentUser;
    }

    /**
     * Set the value of currentUser
     *
     * @param currentUser new value of currentUser
     */
    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }

    private String userEmail;

    /**
     * Get the value of userEmail
     *
     * @return the value of userEmail
     */
    public String getUserEmail() {
        return userEmail;
    }

    /**
     * Set the value of userEmail
     *
     * @param userEmail new value of userEmail
     */
    public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
    }

    private User user;

    /**
     * Get the value of user
     *
     * @return the value of user
     */
    public User getUser() {
        return user;
    }

    /**
     * Set the value of user
     *
     * @param user new value of user
     */
    public void setUser(User user) {
        this.user = user;
    }

    private Event eventInvited;

    /**
     * Get the value of eventInvited
     *
     * @return the value of eventInvited
     */
    public Event getEventInvited() {
        return eventInvited;
    }

    /**
     * Set the value of eventInvited
     *
     * @param eventInvited new value of eventInvited
     */
    public void setEventInvited(Event eventInvited) {
        this.eventInvited = eventInvited;
    }

    private String userFound;

    /**
     * Get the value of userFound
     *
     * @return the value of userFound
     */
    public String getUserFound() {
        return userFound;
    }

    /**
     * Set the value of userFound
     *
     * @param userFound new value of userFound
     */
    public void setUserFound(String userFound) {
        this.userFound = userFound;
    }

    @ManagedProperty(value = "#{createEvent}")
    CreateEvent eventCreation;

    public CreateEvent getEventCreation() {
        return eventCreation;
    }

    public void setEventCreation(CreateEvent eventCreation) {
        this.eventCreation = eventCreation;
    }

    public void setNotificationBean(NotificationBean notificationBean) {
        this.notificationBean = notificationBean;
    }

    private ScheduleModel eventModel;

    public ScheduleModel getEventModel() {
        return eventModel;
    }

    public void setEventModel(ScheduleModel eventModel) {
        this.eventModel = eventModel;
    }

    private ScheduleEvent event;

    Principal principal/*request.getUserPrincipal()*/;

    public Principal getPrincipal() {
        return principal;
    }

    public void setPrincipal(Principal principal) {
        this.principal = principal;
    }
    FacesContext context;

    private List<Event> myEvents;

    public List<Event> getMyEvents() {
        return myEvents;
    }

    public void setMyEvents(List<Event> myEvents) {
        this.myEvents = myEvents;
    }

    @PostConstruct
    public void init() {

        //this.event = new DefaultScheduleEvent();
        eventModel = new DefaultScheduleModel();
        myEvents = new ArrayList<>();
        context = FacesContext.getCurrentInstance();
        HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
        principal = request.getUserPrincipal();
        this.buildEventList();
        //FIXME do something when this call fails this should not appen!!!
        try {
            showUserHome(pm.getProfile(principal.getName()));
        } catch (UserNotFoundException ex) {
            Logger.getLogger(UserHome.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            currentUser = pm.getProfile(principal.getName());
        } catch (UserNotFoundException ex) {
            Logger.getLogger(UserHome.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    //TODO USED?
    public void showHome() {
    }

    // "Insert Code > Add Business Method")
    public void showUserHome(User user) {
        myEvents = (List<Event>) ((List<Calendar>) user.getCalendarCollection()).get(0).getEventCollection();
        for (Event myEvent : myEvents) {
            EventWrapper eventWrapper = new EventWrapper();
            eventWrapper.setEvent(myEvent);

            eventModel.addEvent(eventWrapper);
        }
    }

    //TODO USED?

    public void showSearchResult() {
    }

    public String viewUserCalendar(String calendar) {
        return calendar;
    }

    /**
     * This method allows the logout from the application and returns the user
     * to the login page
     *
     * @return {@link String} representing the login page
     */
    public String logout() {
        lm.logout();
        return "/index?faces-redirect=true";
    }

    //TODO USED?

    public void options() {
    }

    public void submitSearch() {
        if (!principal.getName().equals(userEmail)) {
            user = sm.findUser(userEmail);
            if (user != null) {
                userFound = user.getName() + " " + user.getSurname();

            }

        }

    }

    //TODO JACOPO VEDI TU

    public Event notificationDetail() {
        Notification notification = this.notificationBean.getNotificationSelected();

        Event event = null;
        if (notification == null) {
            return event;
        }
        try {
            //FIXME only for testing
            event = this.notificationManager.getNotificationDetails(notification.getId());

        } catch (IllegalArgumentException | NotificationNotFoundException ex) {
            Logger.getLogger(UserHome.class.getName()).log(Level.SEVERE, null, ex);
        }

        eventInvited = event;
        return event;
    }

    /**
     *  
     * @param selectEvent
     */
    public void eventDetail(SelectEvent selectEvent) {
        EventWrapper ew = (EventWrapper) selectEvent.getObject();
        selectedEvent = ew.getEvent();
    }

    private void buildEventList() {

        User user = null;

        try {
            user = pm.getProfile(principal.getName());
        } catch (UserNotFoundException ex) {
            this.eventsList = new ArrayList<>();
            return;
        }
        //Build the array list of events
        this.eventsList = new ArrayList<>();
        ArrayList<Event> eventsToCheck;
        try {
            //Get all the user events
            eventsToCheck = userDataLoader.loadEventsBar(user);
        } catch (IllegalArgumentException | CalendarNotFoundEception ex) {
            this.eventsList = new ArrayList<>();
            return;
        }
        DateTimeComparator comparator = DateTimeComparator.getDateOnlyInstance();
        DateTime today = new DateTime();
        for (Event event : eventsToCheck) {
            if (comparator.compare(today, event.getStartingDate()) <= 0) {
                this.eventsList.add(event);
            }
        }

    }

    public String showOtherUserHome(User user) {
        FacesContext.getCurrentInstance().getExternalContext().getFlash().put("user", user.getEmail());

        return "/user/indexOther";
    }
    //TODO USED?

    //TODO USED?
    public void showMonthly() {
    }

    //TODO USED?

    public void showWeekly() {
    }

    //TODO USED?

    public void showDaily() {
    }

    //TODO USED?

    public void createEvent() {
    }

    //TODO USED?

    public void next() {
    }

    //TODO USED?

    public void previous() {
    }
}
